package org.zfes.snowier.common.monitor.jvm;

import java.util.Optional;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;
import org.zfes.snowier.common.monitor.Acquisitor;
import org.zfes.snowier.common.monitor.dto.ClassLoadDto;
import org.zfes.snowier.common.monitor.dto.GcDto;
import org.zfes.snowier.common.monitor.dto.ThreadDto;
import org.zfes.snowier.common.monitor.http.okhttp3.OkHttpManager;
import org.zfes.snowier.common.monitor.jvm.Server;
import org.zfes.snowier.common.monitor.utils.ConfigReader;

import com.alibaba.fastjson.JSON;
public class JVMmonitor {
	
//	private static Logger logger = LoggerFactory.getLogger(JVMmonitor.class.getName());
	
	
	private  String configFile;
	private  String instanceKey;//
	private  String serverDomains;//
	private  String serverRoute;
	
	private  String serverJsonDatakey;
	private  String gcJsonDatakey;
	private  String classJsonDatakey;
	private  String threadJsonDatakey;
	private  Integer pushPeriod;
	
	
	private ScheduledExecutorService scheduledThreadPool ;
	
	
	
	private static JVMmonitor jwmmonitor; 
	
	
	private JVMmonitor(String configFile) {
		initConfig(configFile);
		scheduledThreadPool = Executors.newScheduledThreadPool(1);
	}
	public static JVMmonitor getInstance(String configFile) {
        if (jwmmonitor == null) {
            synchronized (JVMmonitor.class) {
            	if (jwmmonitor == null) {
            		jwmmonitor = new JVMmonitor(configFile);
                }
            }
        }
        return jwmmonitor;
	}
	
	public  void startMonitor() {
		
		scheduledThreadPool.scheduleAtFixedRate(()->{
			
			Optional<Server> serverOp=Acquisitor.getInstanceInfo(instanceKey);
			
			Optional<GcDto> gcOp=Acquisitor.getGc(instanceKey);
			
			Optional<ClassLoadDto>  calzzOp=Acquisitor.getClassload(instanceKey);
			
			Optional<ThreadDto>  threadOP=Acquisitor.getThread(instanceKey);
			
	    	Stream.of(serverDomains.split(",")).forEach(domain->{
	    		
	    		OkHttpManager http= OkHttpManager.newIns().addParam("instanceKey", instanceKey);
	    		if(serverOp.isPresent()) {
	    			http.addParam(serverJsonDatakey,JSON.toJSONString(serverOp.get()));
	    		}
	    		if(gcOp.isPresent()) {
	    			http.addParam(gcJsonDatakey,JSON.toJSONString(gcOp.get()));
	    		}
	    		if(calzzOp.isPresent()) {
	    			http.addParam(classJsonDatakey,JSON.toJSONString(calzzOp.get()));
	    		}
	    		if(threadOP.isPresent()) {
	    			http.addParam(threadJsonDatakey,JSON.toJSONString(threadOP.get()));
	    		}
	    		http.postAsync(serverDomains+serverRoute, jsonResponse -> {
	 	 			//System.out.println(instanceKey+"-push-res :"+ jsonResponse.isok());
	 	 		 	//logger.debug(instanceKey+"-push-res :"+ jsonResponse); 
	 	 		});
	    	});
			
		}, 0L,pushPeriod, TimeUnit.SECONDS);
		
		System.out.println("jvm-monitor-stared.....");
	}


	
			
	private void initConfig(String configFile) {
		this.configFile=configFile;
		this.instanceKey=getConfig("jvmInstanceKey");
		this.serverDomains=getConfig("jvmServerDomains");
		this.serverRoute=getConfig("jvmServerRoute");
		
		this.serverJsonDatakey=getConfig("jvmServerJsonDatakey");
		this.gcJsonDatakey=getConfig("jvmGcJsonDatakey");
		this.classJsonDatakey=getConfig("jvmClassJsonDatakey");
		this.threadJsonDatakey=getConfig("jvmThreadJsonDatakey");
		this.pushPeriod=Integer.valueOf(getConfig("jvmPushPeriod"));
		
	}
	
	
	private  String getConfig(String key) {
		Optional<String> valueOp =ConfigReader.getConfig(configFile, key);
		if(!valueOp.isPresent()) {
			throw new RuntimeException("未正确配置"+key);
		}	
		return valueOp.get();
	}

}
